Developer --> Technical Publications
PATH  Mac OS X Server Documentation > Mac OS X Server Release Notes


[Back]

MacOS X Server Release Notes Copyright \xa9 1998 by Apple Computer, Inc. All Rights Reserved.

MacOS X Server Developer Release Notes:
Implications of the Year 2000

For Mac OS X Server, issues related to dates and times and the year 2000 fall into two categories. The first category involves the low-level Mach/BSD core underlying Mac OS X Server. The second category involves the Yellow Box. As this release note explains, date and time values are stored in different formats in these two environments.

Mach/BSD Implications

BSD keeps time as a signed 32-bit value that represents seconds since 1 Jan 00:00:00 GMT 1970. This format can represent times until Jan 19 03:14:07 GMT 2038. Only a couple of parts of BSD—a command and a structure—expect a two-digit year.

The /bin/date command sets the date from the command line. The standard BSD version of the date command takes the following arguments:

date [ -n ] [ -u ] [ yymmddhhmm[.ss] ]

where yy is the year, mm is the month (01-12), dd is the day (01-31), hh is the hour (00-23), mm is the minute (00-59), and ss is the second (00-59). Apple has extended the command in the following compatible format to accept four-digit years:

date [ -n ] [ -u ] [ [yy]yymmddhhmm[.ss] ]

If only a two-digit year (yy) is entered, the command assumes the year to be 19yy. If a four-digit year is entered, then it takes the entire value. Obviously, the latter option is preferable, in light of the year 2000 problem.

The C structure tm also assumes a bias of 1900. It contains a field tm_year whose value is years since 1900. Application code must resolve numbers larger than 99 in this field. For example, if the date is Feb 11, 2000, the tm_year field contains 100. This means that application code that formats a date string by using the following printf statement will be incorrect after the year 2000:

    printf("%d/%d/%d", tm.tm_mon, tm.tm_mday, tm.tm_year); 

Given the above date, this statement would produce the string "2/11/100".

Yellow Box Implications

Mac OS X Server developers writing software using the Yellow Box APIs should be aware of the following issues relating to dates and times. They should also remember that the Yellow Box depends on a platform's operating system to deliver the current time and other pieces of information. Any implementation defects at that layer could also affect the functioning of the Yellow Box APIs.

NSDates and the Year 2000

Dates are represented in Foundation with NSDate (and NSCalendarDate) objects and NSTimeInterval values. An NSTimeInterval is essentially a C-language double. NSDates (and NSCalendarDates) store the date that they represent with an NSTimeInterval, which represents the time delta, in seconds, from the Foundation reference date, which is 00:00:00 1 January 2001 GMT. This time delta is thus negative until the reference date transpires. NSDate objects accord no special significance to the year 2000 or to NSTimeInterval values. However, refer to the topic Risks in Parsing and Displaying Dates, below, for more information on issues in date presentation and the year 2000.

Since Foundation's internal time representation will "cross" zero (the reference date) at some point in the future, there will be a instant, on the order of microseconds, in which an NSDate object created to represent the current time will have an NSTimeInterval of 0.0. (This is unlike some other schemes that set the epoch to a date "always" in the past.) The length of this instant depends upon the resolution of the system time provided by the particular operating system and platform on which application is running. An NSTimeInterval of 0.0 has no special significance to NSDate or NSCalendarDate, but applications that use the NSTimeInterval of a date object in division should protect against division by zero. A more common problem might occur when applications use NSTimeIntervals to represents the delta between two arbitrary date objects (such as when timing events); applications should take appropriate caution in using such values (this is always a good idea apart from date usage).

Risks in Parsing and Displaying Dates

As with any communication between a program and a user, there can be miscommunication. A user can misinterpret a displayed date and a program can misinterpret a date that the user enters. While an application cannot control what the user does, it can avoid doing certain things with dates to reduce the potential for confusion, ambiguity, and data corruption. Namely, it can:

Each of these points is explained in greater detail below. Whenever it is important (or critical) that the user get accurate date information from the application, or that the application get accurate date information from the user, an application should avoid the ambiguous behaviors described below. It should also require strict conformance to a fully specified input format (for user input) and provide as output an equally unambiguous description of dates. (Alternatively, an application could ask for confirmation of input dates, but this seems to be rather "heavyweight.")

Avoid two-digit years and all uses of the "%y" date format specifier.

Per POSIX and ANSI C (refer to section 7.12, ANSI/ISO 9899-1990 for ANSI C definitions), a two-digit year YY means 1900 + YY. The Foundation follows the lead of ANSI C here. Thus, when a user types "5/10/02" in a text field with a date formatter with format "%d/%m/%y", Foundation creates a date of 5 October 1902 instead of 5 October 2002, which the user probably meant. Since "%y" means "two-digit year," the user cannot type anything that will get them a date in the year 2002 (for example, if the user types "5/10/2002" in this example, a date of 5 October 1920 will be successfully parsed). The date-parsing routines parse at most two-digits for "%y" in order to support dates formatted like "980409" (also not a good idea). Conversely, a user has no way of knowing whether "28/10/33" refers to 1933 or 2033 if they see that displayed on the screen or in printed output. To avoid these problems, a program should use "%Y" in the format string instead.

Avoid natural language date parsing.

The natural language parser is pretty sophisticated, but it is after all just sophisticated guessing. The natural language parser is also usually successful at creating a date from input, as long as the input is moderately close to something that looks like a date. However, this may not be the date the user intended. Consequently, don't enable natural language parsing for date formatters. If it is enabled, and the user's input does not match the date formatter's format, the input string is given to the natural language parser.

Here is an example where the natural language parser may fail to parse the date the user intended: suppose the date formatter has a format "%d/%m/%Y" and the user types in "5-10-2002". This string does not match the format (which has slashes), so the date formatter gives the input to the natural language parser. Now, what the "5" means and what the "10" means is ambiguous: it could equally be month-day-year or day-month-year. The natural language parser prefers a particular ordering, given by the NSDateTimeOrdering preference. If the user's preferred language is French, this is DMYH (denoting the ordering day month year hour). The built-in default, if the user has no preferred language, is MDYH (denoting the ordering month day year hour). NSDateTimeOrdering could also be set explicitly to something else by the user. If the user's preferred language is French, the date is "correctly" parsed as 5 October 2002. If the user has no preferred language, it will be parsed as 10 May 2002. In general, an application writer can't know beforehand what the preferences of the user will be. If natural language parsing is desired, an application should take into account this and other issues (such as use of 12- or 24-hour hour designations).

Avoid time-zone abbreviations.

Time-zone abbreviations are inherently ambiguous. Many time zones around the world map to the same abbreviations, by local convention, and there is usually very little information in the abbreviations (most abbreviations derive from phrases such as "Something Standard Time" or "Something Daylight Time," where the Something is the only differentiator). A time of 11:00 CST means something different to a person in New York, New York, U.S.A. (indicating time in Chicago) than someone in Sydney, Australia (indicating time in Darwin). That hour by itself is also ambiguous, since it could be ante meridiem or post meridiem. Use of time-zone names of the form GMT+hhmm and GMT-hhmm (as in GMT+0100) can also be problematic, since the user cannot know which convention (simple offset, or the POSIX minutes-west) is being used. Thus, GMT+0200 can indicate either Helsinki or the mid-Atlantic. See the next section, "Foundation's Time Zone Data," for more information about time-zone representation.

The Yellow Box on Other Operating Systems

The same core Yellow Box frameworks that are part of Mac OS X Server are available on other platforms, including platforms that support WebObjects. Application developers writing Yellow Box code as prescribed above therefore need not worry about year 2000 issues in the Yellow Box world. It is up to operating system vendors to manage year 2000 implications in their low-level operating system. To obtain details about how specific operating systems do this, contact the vendors. The current list of other supported environments for WebObjects and Yellow Box are Microsoft Windows NT, Microsoft Windows 95, Hewlett-Packard HP-UX, and Sun Microsystems Solaris 2.x.